package lib

import (
	"GameServer/Common/data"
	"GameServer/Common/utils"
	"GameServer/Game/errors"
	"GameServer/Game/m"
	"GameServer/Game/sp"
	"GameServer/globalFunc"

	log "github.com/sirupsen/logrus"
)

//  获取玩家好友类型，0-游戏好友 1-FB好友
func GetUserFriendType(u *m.User) (friendType int64) {
	// 0-游戏好友 1-FB好友
	friendType = 0
	if u.Platform == 3 {
		friendType = 1
	}
	return
}

// 获取玩家好友的uid
func GetFriendsUidLst(u *m.User) (r []string) {
	r = make([]string, 0)
	fData := u.GetUserFriendsData()
	for key := range fData.FriendsLst {
		r = append(r, key)
	}
	return
}

// 强制设置上次刷新时间
func ForceResetFriendsData(u *m.User) {
	// 获得玩家的，好友信息
	fData := u.GetUserFriendsData()
	fData.LastRestTime = utils.TNow().Unix()
	fData.SendRecord = 0
	fData.ReciveRecord = 0
	fData.TotalReciveNum = 0
	fData.DailyReqFriendNum = 0
	if len(fData.FriendsLst) > 0 {
		for _, theFriend := range fData.FriendsLst {
			theFriend.ReciveCount = 0  // 剩余，可领取数量
			theFriend.ReciveRecord = 0 // 历史，领取次数
			theFriend.SendCount = 0    // 历史已赠送次数
		}
	}
	fData.Update(fData)
}

// 获取FriendsRewards.json中ID对应的奖励
func GetFriendsRewardInfo(id int64) (rewards []m.BaseKV, err error) {
	rewards = make([]m.BaseKV, 0)
	tpl, ok := data.Get("FriendsRewards", uint64(id))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有找到好友奖励,FriendsRewards")
		log.WithFields(log.Fields{
			"err":    err.Error(),
			"method": "GetFriendsRewardInfo",
			"id":     id,
		}).Debug("没有找到好友奖励,FriendsRewards")
		return nil, err
	}
	t := tpl.(data.FriendsReward)
	for _, info := range t.Rewards {
		rewards = append(rewards, m.BaseKV{
			Key: int64(info.Key),
			Val: int64(info.Value),
		})
	}
	return rewards, nil
}

// 请求UID的对方玩家，加自己为好友
func ReqMakeFriendsWithPlayer(u *m.User, targetFriendsUid string) (err error) {
	// 获得玩家的，好友信息
	fData := u.GetUserFriendsData()
	defer fData.Update(fData)
	fLst := fData.FriendsLst
	nowTime := utils.TNow().Unix()
	// 检查目标是否已经是玩家的好友
	_, findFriend := fLst[targetFriendsUid]
	if findFriend { // 已经是好友了，不走添加好友逻辑
		err = errors.NewErrcode(data.Errcode.ServerErr, "已经是好友关系") // 999
		return err
	}
	// 检查被ban列表
	banData, findInBan := fData.ReqBanFriendsLst[targetFriendsUid]
	if findInBan {
		if nowTime-banData.LastRefuseTime >= 86400 {
			fData.RemoveInBanLst(targetFriendsUid) // 删除ban历史列表
		} else {
			err = errors.NewErrcode(data.Errcode.UnionIsBan, "暂时不能添加对方好友") // 6007
			return err
		}
	}
	// 获取对方玩家m.User
	targetUser, ok := globalFunc.GetUserByUID(targetFriendsUid)
	if ok == false {
		err = errors.NewErrcode(data.Errcode.UserNotFound, "没有找到对方玩家U") // 1001
		return err
	}
	targetFData := targetUser.GetUserFriendsData()
	// 检查是否已经请求过了
	_, findInReqLst := targetFData.ReqFriendsLst[u.Uid.Hex()]
	if findInReqLst == false {
		fData.DailyReqFriendNum = fData.DailyReqFriendNum + 1 // 累加申请
		targetFData.AddReqFriendLst(u.Uid.Hex())
		if targetUser.IsOnLine() {
			globalFunc.BroadData(targetUser.Uid.Hex(), &sp.NoticeReqFriendLstChangeRequest{
				ReqFriendsLst: FormatSimpleFriendsDat(targetFData.ReqFriendsLst),
			})
		}
	}
	return nil
}

// 拒绝好友请求
func ReqFriends_Refuse(u *m.User, targetFriendsUid string) {
	fData := u.GetUserFriendsData() // 获取玩家好友信息
	_, find := fData.ReqFriendsLst[targetFriendsUid]
	if find == false {
		return
	}
	nowTime := utils.TNow().Unix()
	// 从自己的申请列表中，移除这个玩家
	fData.RemoveReqFriendLst(targetFriendsUid)
	// 告知对方，被拒绝
	targetUser, ok := globalFunc.GetUserByUID(targetFriendsUid)
	if ok {
		targetFData := targetUser.GetUserFriendsData()
		targetFData.AddInBanLst(u.Uid.Hex(), nowTime)
	}
}

// 接受好友请求
func ReqFriends_Accept(u *m.User, targetFriendsUid string) {
	fData := u.GetUserFriendsData() // 获取玩家好友信息
	_, find := fData.ReqFriendsLst[targetFriendsUid]
	if find == false {
		return
	}
	// 交友
	MakeFriendsWithPlayer(u, targetFriendsUid)
}

// 和UID的对方玩家交朋友，强行邀为同道
func MakeFriendsWithPlayer(u *m.User, targetFriendsUid string) (err error) {
	// 获得玩家的，好友信息
	fData := u.GetUserFriendsData()
	fLst := fData.FriendsLst

	// 检查目标是否已经是玩家的好友
	_, findFriend := fLst[targetFriendsUid]
	if findFriend { // 已经是好友了，不走添加好友逻辑
		err = errors.NewErrcode(data.Errcode.ServerErr, "已经是好友关系")
		return
	}

	// 获取对方玩家m.User
	targetUser, ok := globalFunc.GetUserByUID(targetFriendsUid)
	if ok == false {
		err = errors.NewErrcode(data.Errcode.UserNotFound, "没有找到对方玩家U")
		return
	}
	// 互相不为好友
	// 1.玩家添加对方
	targetFriendType := GetUserFriendType(targetUser)
	targetFriendData := &m.FriendsBaseData{
		Uid:          targetUser.Uid.Hex(),
		FriendTyp:    targetFriendType, // 0-游戏好友 1-FB好友
		ReciveCount:  0,
		ReciveRecord: 0,
		SendCount:    0,
	}
	fData.AddFriend(targetFriendData)

	// 2.对方添加玩家
	targetFData := targetUser.GetUserFriendsData()
	targetFLst := targetFData.FriendsLst
	// 检查目标是否已经是对方的好友
	_, findFriend = targetFLst[u.Uid.Hex()]
	if findFriend { // 已经是好友了，不走添加好友逻辑
		err = nil
		return
	}
	playerFriendType := GetUserFriendType(u)
	playerFriendData := &m.FriendsBaseData{
		Uid:          u.Uid.Hex(),
		FriendTyp:    playerFriendType, // 0-游戏好友 1-FB好友
		ReciveCount:  0,
		ReciveRecord: 0,
		SendCount:    0,
	}
	targetFData.AddFriend(playerFriendData)
	return
}

// 和UID的对方玩家解除好友关系 -- 被通知对方已被拒绝
func DeleteFriends(u *m.User, targetFriendsUid string) (err error) {
	// 获得玩家的，好友信息
	fData := u.GetUserFriendsData()
	// 获取对方玩家m.User
	targetUser, ok := globalFunc.GetUserByUID(targetFriendsUid)
	if ok == false {
		err = errors.NewErrcode(data.Errcode.UserNotFound, "没有找到对方玩家U")
		return
	}
	targetFData := targetUser.GetUserFriendsData()
	// 调用M层的deleteFriend，不是这个
	// 1.玩家删除对方
	fData.DeleteFriend(targetFriendsUid)
	// 2.对方删除玩家
	targetFData.DeleteFriend(u.Uid.Hex())
	targetFData.AddInBanLst(u.Uid.Hex(), utils.TNow().Unix())
	return
}

// 给好友赠送礼物
func SendGiftToFriend(u *m.User, friendUID string, num int64) {
	// 获得玩家的，好友信息
	fData := u.GetUserFriendsData()
	// 检查目标是否已经为好友
	theFriend, findFriend := fData.FriendsLst[friendUID]
	if findFriend == false {
		return
	}
	// 不允许重复赠送
	if theFriend.SendCount > 0 {
		return
	}
	// 获取好友m.User
	ufriend, ok := globalFunc.GetUserByUID(friendUID)
	if ok == false || ufriend == nil {
		return
	}
	// 处理自身数据
	fData.SendRecord = fData.SendRecord + num       // 历史赠送次数记录，累加
	theFriend.SendCount = theFriend.SendCount + num // 好友赠送次数记录，累加
	fData.Update(fData)                             // 更新数据
	// 成就，记录赠送好友礼物次数。num
	AddAchievProgress(u, data.AchievementType.SendGift_friends, num)

	// 处理好友数据
	ReciveFriendsGift(ufriend, u.Uid.Hex(), num)
	return
}

// 给所有好友赠送礼物
func SendGiftToFriendAll(u *m.User, num int64) {
	// 获得玩家的，好友信息
	fData := u.GetUserFriendsData()
	if fData.FriendsLst == nil || len(fData.FriendsLst) == 0 {
		return
	}
	var totalSendCount int64 = 0
	sendUIDMap := make(map[string]int64, 0)
	for Uid, theFriend := range fData.FriendsLst {
		if theFriend.SendCount == 0 { // && totalSendCount < 20
			theFriend.SendCount = theFriend.SendCount + num
			totalSendCount = totalSendCount + num
			sendUIDMap[Uid] = 1
			// 成就，记录赠送好友礼物次数。num
			AddAchievProgress(u, data.AchievementType.SendGift_friends, num)
		}
		// if totalSendCount >= 20 {
		// 	break
		// }
	}
	// 处理自身数据
	fData.SendRecord = fData.SendRecord + totalSendCount
	fData.Update(fData)
	// 处理好友数据
	for uid, _ := range sendUIDMap {
		ufriend, ok := globalFunc.GetUserByUID(uid)
		if ok && ufriend != nil {
			ReciveFriendsGift(ufriend, u.Uid.Hex(), num)
		}
	}
	return
}

// 接收到好友的礼物
func ReciveFriendsGift(u *m.User, friendUID string, num int64) {
	// 获得玩家的，好友信息
	fData := u.GetUserFriendsData()
	// 检查目标是否已经为好友
	theFriend, findFriend := fData.FriendsLst[friendUID]
	if findFriend == false {
		return
	} else {
		theFriend.ReciveCount = theFriend.ReciveCount + num
	}
	// 更新数据
	fData.TotalReciveNum = fData.TotalReciveNum + num
	fData.Update(fData)
	// 通知收到礼物
	if u.IsOnLine() {
		globalFunc.BroadData(u.Uid.Hex(), &sp.NoticeReciveFriendGiftRequest{
			ReciveRecord:   fData.ReciveRecord,
			TotalReciveNum: fData.TotalReciveNum,
		})
	}
	return
}

// 获取UID好友的礼物
func GetFriendsGiftByUID(from string, u *m.User, friendUID string, PSend func(interface{}) error) (uProp *m.UpdateProp, resGoods []*m.Goods, boxResList []*m.BoxRes, err error) {
	// 获得玩家的好友信息
	fData := u.GetUserFriendsData()
	// 检查目标是否已经为好友
	theFriend, findFriend := fData.FriendsLst[friendUID]
	if findFriend == false {
		err = errors.NewErrcode(data.Errcode.UserNotFound, "对象不为好友")
		return
	}
	if fData.ReciveRecord >= data.OneDayFriendsGiftReciveLimit {
		err = errors.NewErrcode(data.Errcode.ServerErr, "已到达接收礼物上限")
		return
	}
	// 检查是否有礼物可以领取
	if theFriend.ReciveCount > 0 {
		var realReciveCount int64 = theFriend.ReciveCount
		fData.TotalReciveNum = fData.TotalReciveNum - realReciveCount
		fData.ReciveRecord = fData.ReciveRecord + realReciveCount
		if fData.TotalReciveNum < 0 {
			fData.TotalReciveNum = 0
		}
		theFriend.ReciveRecord = theFriend.ReciveRecord + theFriend.ReciveCount
		theFriend.ReciveCount = 0
		fData.Update(fData) // 更新
		// 准备礼物
		var resList []m.BaseKV
		resList, err = GetFriendsRewardInfo(1)
		if err != nil {
			return
		}
		uProp, resGoods, boxResList, err = GiveGoodsByKvList(from, u, resList, PSend)

		// 成就，记录接受赠礼次数
		AddAchievProgress(u, data.AchievementType.Receive_gift, realReciveCount)
		return
	} else {
		err = errors.NewErrcode(data.Errcode.ServerErr, "没有礼物可以领取")
		return
	}
}

// 获取所有好友的礼物
func GetFriendsGiftAll(from string, u *m.User, PSend func(interface{}) error) (uProp *m.UpdateProp, resGoods []*m.Goods, boxResList []*m.BoxRes, err error) {
	// 获得玩家的好友信息
	fData := u.GetUserFriendsData()
	if fData.FriendsLst == nil || len(fData.FriendsLst) == 0 {
		return
	}
	if fData.ReciveRecord >= data.OneDayFriendsGiftReciveLimit {
		err = errors.NewErrcode(data.Errcode.ServerErr, "已到达接收礼物上限")
		return
	}
	defer fData.Update(fData) // 更新
	var canReciveNum int64 = data.OneDayFriendsGiftReciveLimit - fData.ReciveRecord
	var realReciveNum int64 = 0
	for _, theFriend := range fData.FriendsLst {
		if canReciveNum > 0 {
			if theFriend.ReciveCount > 0 {
				fData.TotalReciveNum = fData.TotalReciveNum - theFriend.ReciveCount
				if fData.TotalReciveNum < 0 {
					fData.TotalReciveNum = 0
				}
				canReciveNum = canReciveNum - theFriend.ReciveCount
				realReciveNum = realReciveNum + theFriend.ReciveCount
				fData.ReciveRecord = fData.ReciveRecord + theFriend.ReciveCount
				theFriend.ReciveRecord = theFriend.ReciveRecord + theFriend.ReciveCount
				theFriend.ReciveCount = 0
			}
		} else {
			break
		}
	}
	if realReciveNum > 0 {
		resListConfig, errGetConfig := GetFriendsRewardInfo(1)
		if errGetConfig != nil {
			return
		}
		resList := make([]m.BaseKV, 0)
		for i := int64(0); i < realReciveNum; i++ {
			// 准备礼物
			for _, res := range resListConfig {
				resList = append(resList, m.BaseKV{
					Key: res.Key,
					Val: res.Val, // 数量 * 实际接收的份数
				})
			}
		}
		uProp, resGoods, boxResList, err = GiveGoodsByKvList(from, u, resList, PSend)
		if err != nil {
			return
		}
		// 成就，记录接受赠礼次数
		AddAchievProgress(u, data.AchievementType.Receive_gift, realReciveNum)
	}
	return
}

// 记录好友分享次数
func RecordShareNum(us *m.User, limitNum int64) (err error) {
	// 获得玩家的好友信息
	fData := us.GetUserFriendsData()

	if fData.ShareNum > limitNum {
		err = errors.NewErrcode(data.Errcode.ShareLimitNum, "分享好友次数奖励达达到上限")
		return
	}
	// 记录好友分享次数
	fData.ShareNum++
	fData.Update(fData)
	return
}
